package cn.wx.scholar.tool.nio;

import org.apache.commons.lang.StringUtils;
import java.io.*;
import java.util.HashMap;
import java.util.Map;  

public class FileUtil {

    /** 
     * 通过BufferedRandomAccessFile读取文件,推荐 
     * 
     * @param file     源文件 
     * @param encoding 文件编码 
     * @param pos      偏移量 
     * @param num      读取量 
     * @return pins文件内容，pos当前偏移量 
     */  
    public static Map<String, Object> BufferedRandomAccessFileReadLine(File file, File wFile, String encoding, long pos, int num) {
    	
        BufferedRandomAccessFile reader = null;

        
        Map<String, Object> res = new HashMap<>();
        BufferedWriter output = null;
        try {
        	/**
        	 * 读取文件
        	 */
            reader = new BufferedRandomAccessFile(file, "r",1024);

            //DataOutputStream out = new DataOutputStream(new BufferedOutputStream(new FileOutputStream(wFile)));
            
            
            output = new BufferedWriter(
            		new OutputStreamWriter(
            				new FileOutputStream(wFile)));
            
            /**
             * 要写入文件
             */
            
            
            reader.seek(pos);
            for (int i = 0; i < num; i++) { 
            	
	            final String pin = reader.readLine();
	            
	            if (StringUtils.isBlank(pin)) {  
	                break;  
	            }
	            output.append(pin + "\r");
	            res.put("pins", i+1);
	            
            }
            
            res.put("pos", reader.getFilePointer());
            
            
        } catch (Exception e) {  
            e.printStackTrace();  
        } finally {
        	try {
				reader.close();
				reader = null;
			} catch (IOException e) {
				e.printStackTrace();
			}
        }
        
        return res;  
    } 
    
    
    
    public static int splitBigData(final String filePath) throws Exception {
		
        int bufferSize = 20 * 1024 * 1024;//设读取文件的缓存为20MB   
        //建立缓冲文本输入流   
        File file = new File(filePath);//"D:\\mag_papers_0.txt"  
        FileInputStream fileInputStream = new FileInputStream(file);  
        BufferedInputStream bufferedInputStream = new BufferedInputStream(fileInputStream);
        //注意这里有时会乱码，根据自己的文本存储格式，进行调整
        InputStreamReader inputStreamReader = new InputStreamReader(bufferedInputStream,"utf-8");  
        BufferedReader input = new BufferedReader(inputStreamReader, bufferSize);
        
        String line;
        int split_ = 0;
        int size = 0;
        BufferedWriter output = null;
        
        try {
        	while((line = input.readLine()) != null) {
            	
            	if(split_ == 0) {
            		output = new BufferedWriter(
                    		new OutputStreamWriter(
                    				new FileOutputStream( 
                    						new File("D:\\my_mag\\part" + (size++) + ".txt")),"utf-8"));
            	}
            	
            	output.append(line + "\r");
            	
            	/**
            	 * 每20000个数据 分一片
            	 */
            	if(split_ > 19998) {
            		output.flush();  
                    output.close();  
                    output = null;
                    split_=0;
            	}else {
            		split_ ++;
            	}
            	
            }
        }catch (Exception e) {
        	
		}finally {
			if(output != null) {
				output.flush();  
	            output.close();  
	            output = null;
			}
		}
       
        input.close();  
        
        return size;
	}
    
    
    public static void main(String[] args) throws Exception {
    	
    	long start = System.currentTimeMillis(); 
    	
    	//splitBigData("D:\\mag_papers_0.txt");
    	
    	File file = new File("D:\\mag_papers_0.txt");
    	
        long pos = 0L;  
        
        int t = 0;
        
        while (true) {
        	
        	File wfile = new File("D:\\my_mag\\part" + t + ".txt");
        	
            Map<String, Object> res = FileUtil.BufferedRandomAccessFileReadLine(file, wfile, "UTF-8", pos, 20000);  
            
            Integer pins = (Integer)res.get("pins");

            if (pins == null || pins < 20000) {  
                break;
            }  

            pos = (Long) res.get("pos");
            t++;
        }
        
        System.out.println(((System.currentTimeMillis() - start) / 1000) + ""); 

    }
}
